package com.ant.storage.service;


import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @author hzd
 * @version 1.0
 * @date 2022/12/2 14:44@Component
 * @ServerEndpoint("/webSocket/{userId}")
 */
@Slf4j
@Component
@ServerEndpoint("/webSocket/{userId}")
public class WebSocketServer {

    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;
    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();

    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;

    //接收sid
    private String sid="";
    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session,@PathParam("userId") String userId) {
        this.session = session;
        this.sid = userId;

        //加入set中
        webSocketSet.add(this);

        //在线数加1
        addOnlineCount();
        log.info("有新窗口开始监听:"+userId+",当前在线人数为" + getOnlineCount());
        try {
            sendMessage("ok");
        } catch (IOException e) {
            log.error("websocket IO异常");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        //从set中删除
        webSocketSet.remove(this);
        //在线数减1
        subOnlineCount();
        log.info("有一连接关闭！当前在线人数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到来自窗口"+sid+"的信息:"+message);
        //群发消息
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.info("非正常关闭,发生错误!====>" + error.toString() + "当前在线人数为" + getOnlineCount());
    }
    /**
     * 实现服务器主动推送
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }


    /**
     * 群发自定义消息
     * */
    public static void sendInfo(String message,@PathParam("sid") String sid) throws IOException {
        log.info("推送消息到窗口"+sid+"，推送内容:"+message);
        for (WebSocketServer item : webSocketSet) {
            try {
                //这里可以设定只推送给这个sid的，为null则全部推送
                if(sid==null) {
                    item.sendMessage(message);
                }else if(item.sid.equals(sid)){
                    item.sendMessage(message);
                }
            } catch (IOException e) {
                continue;
            }
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }

//    /**
//     * 静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
//     */
//    private static int onlineCount = 0;
//
//    /**
//     * concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
//     */
//    //private static ConcurrentHashMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
//    //存放所有的websocket连接
//    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
//
//    /**
//     * 与某个客户端的连接会话，需要通过它来给客户端发送数据
//     */
//    private Session session;
//    /**
//     * 接收userId
//     */
//    private String userId = "";
//
//    public static String baseUrl = "http://192.168.6.170:9529";
//    /**
//     * 连接建立成功调用的方法
//     */
//    @OnOpen
//    public void onOpen(Session session, @PathParam("userId") String userId) {
//        this.session = session;
//        this.userId = userId;
//        //加入map
//        if (webSocketSet.contains(this.userId)) {
//            webSocketSet.remove(this.userId);
//            webSocketSet.add(this);
//        } else {
//            webSocketSet.add(this);
//            addOnlineCount(); //在线数加1
//        }
//        log.info("有新窗口开始监听:"+userId+",当前在线人数为" + getOnlineCount());
//        try {
//            sendMessage("ok");
//        }catch (IOException e){
//            log.error("用户:"+userId+",网络异常!!!!!!");
//        }
//
//    }
//
//    /**
//     * 连接关闭调用的方法
//     */
//    @OnClose
//    public void onClose() {
//        webSocketSet.remove(this);
//        subOnlineCount();
////        if (webSocketMap.containsKey(userId)) {
////            webSocketMap.remove(userId);
////        }
//        log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount());
//    }
//
//    /**
//     * 收到客户端消息后调用的方法
//     *
//     * @param message 客户端发送过来的消息*/
//    @OnMessage
//    public void  onMessage(String message,Session session){
//        log.info("用户消息:" + userId + ",报文:" + message);
//        for (WebSocketServer item : webSocketSet){
//            try {
//                item.sendMessage(message);
//            }
//            catch (IOException e){
//                e.printStackTrace();
//            }
//        }
//        //可以群发消息
//        //消息保存到数据库、redis
////        if(StringUtils.isNotBlank(message)){
////            try {
////                //解析发送的报文
////                JSONObject jsonObject=JSON.parseObject(message);
////                //追加发送人(防止串改)
////                jsonObject.put("fromUserId",this.userId);
////                String toUserId=jsonObject.getString("toUserId");
////                //传送给对应toUserId用户的websocket
////                if(StringUtils.isNotBlank(toUserId) && webSocketMap.containsKey(toUserId)){
////                    webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
////                }else{
////                    log.error("请求的userId:"+toUserId+"不在该服务器上");
////                    //否则不在这个服务器上，发送到mysql或者redis
////                }
////            }catch (Exception e){
////                e.printStackTrace();
////            }
////        }
//    }
//
//
//
//    /**
//     *
//     * @param session
//     * @param error
//     */
//    @OnError
//    public void onError(Session session, Throwable error) {
//        log.error("用户错误:"+this.userId+",原因:"+error.getMessage());
//        error.printStackTrace();
//    }
//
//    /**
//     * 实现服务器主动推送
//     */
//    public void sendMessage(String message) throws IOException {
//        synchronized (session){
//            this.session.getBasicRemote().sendText(message);
//        }
//    }
//
//    /**
//     * 发送自定义消息
//     * */
//    public static void sendInfo(String message,@PathParam("userId") String userId) throws IOException {
//        log.info("发送消息到:" + userId + "，报文:" + message);
//        for (WebSocketServer item :webSocketSet){
//            try {
//                if(userId==null){
//                    item.sendMessage(message);
//                }else if(item.userId.equals(userId)){
//                    item.sendMessage(message);
//                }
//            }catch (IOException e){
//                continue;
//            }
//        }
//
//
////        if (StringUtils.isNotBlank(userId) && webSocketMap.containsKey(userId)) {
////            webSocketMap.get(userId).sendMessage(message);
////        } else {
////            log.error("用户" + userId + ",不在线！");
////        }
//    }
//
//
//    /**
//     * 实现服务器主动推送- byte数组
//     */
//    public void sendAudio(byte[] data) throws IOException {
//        ByteBuffer buffer = ByteBuffer.wrap(data);
//        this.session.getBasicRemote().sendBinary(buffer);
//    }
//
//    /**
//     * 群发自定义消息-发送音频文件
//     * */
//    public static void sendToAudio(String message){
//        InputStream inputStream = null;
//        for (WebSocketServer item : webSocketSet) {
//            try {
//                inputStream = sendGet(message);
//                byte[] bytes = IOUtils.toByteArray(inputStream);
//                item.sendAudio(bytes);
//            } catch (Exception e) {
//            }
//        }
//    }
//
//    public static InputStream sendGet(String message) {
//        InputStream inputStream = null;
//        try {
//            String url = encode(baseUrl,message);
//            URL serverUrl = new URL(url);
//            URLConnection connection = serverUrl.openConnection();
//            //设置超时时间
//            connection.setConnectTimeout(5000);
//            connection.setReadTimeout(15000);
//            connection.setRequestProperty("accept", "*/*");
//            connection.setRequestProperty("connection", "Keep-Alive");
//            connection.connect();
//            inputStream = connection.getInputStream();
//        } catch (Exception e){
//            e.printStackTrace();
//        }
//        return inputStream;
//    }
//    public static String encode(String baseUrl, String message) throws UnsupportedEncodingException {
//        String title = "format: yaml\nmode: mspk\naudio: 14\nspeaker: Aida\nvocoder: melgan";
//        String encodeContent = URLEncoder.encode(message, "UTF-8");
//        String encodeTitle = URLEncoder.encode(title, "UTF-8");
//        String result = baseUrl + "/synthesize?text=" + encodeContent + "&kwargs=" + encodeTitle;
//        log.info("request path : {}",result);
//        return result;
//    }
//
//    public static synchronized int getOnlineCount() {
//        return onlineCount;
//    }
//
//    public static synchronized void addOnlineCount() {
//        WebSocketServer.onlineCount++;
//    }
//
//    public static synchronized void subOnlineCount() {
//        WebSocketServer.onlineCount--;
//    }

}
